#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>

#include "Sock.hpp"
#include "Log.hpp"

using func_t = std::function<std::string(std::string&)>;
class HttpServer;

class ThreadData
{
public:
    ThreadData(std::string clientip, uint16_t clientport, int sock, HttpServer *t) : ip_(clientip), port_(clientport),
                                                                                     sock_(sock), current(t)
    {
    }

    ~ThreadData() {}

public:
    std::string ip_;
    uint16_t port_;
    int sock_;
    HttpServer *current;
};

class HttpServer
{
public:
    HttpServer(func_t f, uint16_t port) : func(f), port_(port)
    {
    }
    void InitServer()
    {
        // 创建套接字
        listensock_.Socket();
        // 绑定套接字
        listensock_.Bind(port_);
        // 监听--与客户端建立连接
        listensock_.Listen();
    }
    void Start()
    {
        while (true)
        {
            std::string clientip;
            uint16_t clientport;
            // 创建新的套接字
            int sock = listensock_.Accept(&clientip, &clientport);

            // 用线程来处理任务
            pthread_t pt;
            ThreadData *td = new ThreadData(clientip, clientport, sock, this);
            pthread_create(&pt, nullptr, Rountine, td);
        }
    }
    static void *Rountine(void *args)
    {
        pthread_detach(pthread_self()); // 线程分离
        ThreadData *td = static_cast<ThreadData *>(args);
        // 业务处理
        td->current->ServerIO(td->sock_);
        close(td->sock_);
        delete td;
    }
    void ServerIO(int sock)
    {
        // 接收客服端的请求
        char buffer[4096];
        ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (s > 0)
        {
            buffer[s] = 0;
            //std::cout << buffer << std::endl;
            // logMessage(Info, buffer);
        }
        else if (s == 0)
        {
            // std::cout<<"client quit,me too";
            logMessage(Info, "client quit,me too");
            listensock_.Close();
            exit(-1);
        }
        else
        {
            logMessage(Fatal, "code:%d,string:%s", errno, strerror(errno));
            listensock_.Close();
            exit(-1);
        }
        // 业务逻辑处理
        std::string request = buffer;
        std::string reponse = func(request);
        send(sock, reponse.c_str(), reponse.size(), 0);
    }
    ~HttpServer()
    {
    }

private:
    uint16_t port_;
    Sock listensock_;
    func_t func;
};